package server.common.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import server.common.message.NettyMessage;
import server.common.message.NettyMessageFactory;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static server.common.message.NettyMessageFactory.buildLoginResponse;

/**
 * Created by xiangliyou on 17-9-22.
 *
 * @DESCRIPTION （服务端）握手接入和安全认证代码 *
 */
public class LoginAuthRespHandler extends ChannelInboundHandlerAdapter {
    //已登录的IP
    private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<>();
    //可以加上白名单，黑名单....


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyMessage message = (NettyMessage) msg;
        //如果是握手请求消息，则处理，不是就传个下一个
        if (message.getHeader() != null
                && message.getHeader().getType() == NettyMessageFactory.MESSAGE_TYPE_LOGIN_AUTH_REQ_CODE) {
            //获取接入的ip地址，作为存储接入列表的key
            String nodeIndex = ctx.channel().remoteAddress().toString();
            NettyMessage loginResp;
            //如果重复登录,拒绝
            if (nodeCheck.containsKey(nodeIndex)) {
                loginResp = buildLoginResponse(NettyMessageFactory.MESSAGE_TYPE_LOGIN_AUTH_RESULT_FAILURE);
            }
            else {//登录成功
                InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
                String ip = address.getAddress().getHostAddress();

                //白或黑名单检查
                boolean isOk = false;
                //TODO
                isOk = true;

                loginResp = isOk ? buildLoginResponse(NettyMessageFactory.MESSAGE_TYPE_LOGIN_AUTH_RESULT_SUCCESS)//
                        : buildLoginResponse(NettyMessageFactory.MESSAGE_TYPE_LOGIN_AUTH_RESULT_FAILURE);
                if (isOk) {
                    //添加到接入列表
                    nodeCheck.put(nodeIndex, true);
                } else {
                    //认证失败，关闭连接
                    ctx.close();
                }

                System.out.println("The login response is :" + loginResp);
            }
            //发送回复
            ctx.writeAndFlush(loginResp);
            return;
        } else {
            //传递给下一个ChannelHandler
            //ctx.fireChannelRead(msg);
        }
        ctx.fireChannelRead(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    /**
     * 发生异常时的处理
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        //删除缓存
        nodeCheck.remove(ctx.channel().remoteAddress().toString());
        //关闭连接
        ctx.close();
        ctx.fireExceptionCaught(cause);
    }
}
